package serv

import (
	"errors"
	"github.com/skip2/go-qrcode"
	"gorm.io/gorm"
	"log"
	"path/filepath"
	"server/internal/app/model"
	"server/internal/database"
	"server/internal/pkg/qrcodes"
	"server/pkg/tools"
	"strconv"
	"strings"
	"time"
)

var Tissue = new(tissue)

type tissue struct {
	model.Tissue
	HasChildren bool `json:"hasChildren"`
	//TissueArr   []int    `json:"tissue_arr" gorm:"-"`
	Children []tissue `json:"children,omitempty" gorm:"-"`
}

// List 树状图
func (a tissue) List(pid int) []tissue {
	Db := database.DB
	var menus []tissue

	Db.Model(&menus).Where("pid=?", pid).Find(&menus)
	if len(menus) == 0 {
		return nil
	}

	var list []tissue
	for _, v := range menus {
		var count int64
		Db.Table("tissue").Where("pid=?", v.ID).Count(&count)
		v.HasChildren = false
		if count > 0 {
			v.HasChildren = true
		}
		//v.Children = a.List(v.ID)
		list = append(list, v)
	}

	return list
}
func (a tissue) Lists(pid int) []tissue {
	Db := database.DB
	var menus []tissue

	Db.Model(&menus).Where("id=?", pid).Find(&menus)
	if len(menus) == 0 {
		return nil
	}

	var list []tissue
	for _, v := range menus {
		var count int64
		Db.Table("tissue").Where("pid=?", v.ID).Count(&count)
		v.HasChildren = false
		if count > 0 {
			v.HasChildren = true
		}
		//v.Children = a.List(v.ID)
		list = append(list, v)
	}

	return list
}

// Read 单条
func (a tissue) Read(id any) (*gorm.DB, tissue) {
	Db := database.DB
	detail := tissue{}
	Db.Model(&a).Where("id =?", id).First(&detail)
	//detail.TissueArr = tools.StringArrToIntArr(strings.Split(Tissue.GetTissueIdArr(detail.Pid), ","))
	return Db, detail

}

// GetIds 返回当前组织结构id数组
func (a tissue) GetIds(id int) []int {

	return tools.StringArrToIntArr(strings.Split(Tissue.GetTissueIdArr(id), ","))

}

// Create 新增
func (a tissue) Create(data model.Tissue) *gorm.DB {
	Db := database.DB

	t := time.Now()
	data.CreateTime = int(t.Unix())
	data.UpdateTime = int(t.Unix())

	Db = Db.Model(&data).Create(&data)

	//a.GenerateQrcode(a.ID)

	return Db
}

// Update 编辑
func (a tissue) Update(data model.Tissue) *gorm.DB {
	Db := database.DB

	t := time.Now()
	data.UpdateTime = int(t.Unix())

	//a.GenerateQrcode(a.ID)

	return Db.Save(&data)

}

// Delete 删除
func (a tissue) Delete(ids []int) error {
	Db := database.DB
	b := tissue{}
	Db.Model(&a).Where("pid in ?", ids).First(&b)

	if a.ID > 0 {
		return errors.New("存在关联下级，无法删除")
	}

	return Db.Delete(&a, ids).Error

}

type tissueSelect struct {
	Value    int            `json:"value"`
	Label    string         `json:"label"`
	IsLeaf   bool           `json:"isLeaf"`
	Children []tissueSelect `json:"children,omitempty"`
}

// Select 远程下拉
func (a tissue) Select(pid int) []tissueSelect {
	Db := database.DB

	var menus []tissue

	Db.Model(&menus).Where("pid=?", pid).Find(&menus)

	var list []tissueSelect

	if len(menus) == 0 {
		return nil
	}
	for _, v := range menus {
		var count int64
		Db.Table("tissue").Where("pid=?", v.ID).Count(&count)
		IsLeaf := false
		if count > 0 {
			IsLeaf = true
		}
		list = append(list, tissueSelect{
			Value:  v.ID,
			Label:  v.Name,
			IsLeaf: IsLeaf,
			//Children: a.Select(v.ID),
		})
	}

	return list
}

// Selects 远程下拉 pid 不为 0
//func (a tissue) Selects(pid int) []tissueSelect {
//	var list []tissueSelect
//	Db := database.DB
//	var menus tissue
//
//	Db.Model(&menus).Where("id=?", pid).First(&menus)
//	list = append(list, tissueSelect{
//		Value:    menus.ID,
//		Label:    menus.Name,
//		Children: a.Select(pid),
//	})
//	return list
//}

// Selects 远程下拉 pid 不为 0
func (a tissue) Selects(pid int) []tissueSelect {
	var list []tissueSelect
	Db := database.DB
	//Count int `json:"count" `

	var menus tissue

	Db.Model(&menus).Where("id=?", pid).First(&menus)
	var count int64
	Db.Table("tissue").Where("pid=?", menus.ID).Count(&count)
	IsLeaf := false
	if count > 0 {
		IsLeaf = true
	}
	list = append(list, tissueSelect{
		Value:  menus.ID,
		Label:  menus.Name,
		IsLeaf: IsLeaf,
		//Children: a.Select(pid),
	})

	return list
}

func (tissue) GetAreaName(id int) string {

	Db := database.DB
	a := tissue{}
	Db.Model(&a).Where("id=?", id).Find(&a)
	name := a.Name
	pid := a.Pid
	if pid > 0 {
		for {
			a = tissue{}
			Db.Model(&a).Where("id=?", pid).Find(&a)
			if a.ID > 0 {
				name = a.Name + "-" + name
			}
			if a.Pid == 0 {
				break
			}
			pid = a.Pid
		}
	}

	return name
}

func (a tissue) GenerateQrcode(id int) {
	Db := database.DB

	Db.Model(&a).Where("id=?", id).Find(&a)

	//生成二维码
	url := "http://bfr.csjwlkj.cn/wap/#/pages/index/index?eid=" + strconv.Itoa(a.ID)
	t := time.Now()
	logoPath := "public/logo.png"
	fileName := a.Name + t.Format("200601021505") + ".png"
	outPath := filepath.Join(tools.Mkdir("public/upload"), "/", fileName)
	err := qrcodes.CreateQrCodeCustomWithLogoPoster(url, logoPath, outPath, qrcode.Highest, 256, a.Name)
	if err != nil {
		log.Println("二维码生成失败：", err)
	}
	a.Qrcode = outPath
	Db.Model(&a).Updates(&a)

}

func (a tissue) GetTissueIds(pid int, Ids []int) []int {
	Db := database.DB
	var menus []tissue

	Db.Model(&menus).Select("id,pid").Where("pid=?", pid).Find(&menus)

	if len(menus) == 0 {
		return Ids
	}
	if len(Ids) == 0 {
		Ids = append(Ids, pid)
	}
	for _, v := range menus {
		Ids = append(Ids, v.ID)
		Ids = a.GetTissueIds(v.ID, Ids)
	}

	return Ids
}

type tissue2 struct {
	model.Tissue
	EnterpriseNum int `json:"enterprise_num"`
	PeopleNum     int `json:"people_num"`
}

// StatList 带统计的列表
func (a tissue) StatList(Db *gorm.DB) (*gorm.DB, []tissue2, int64) {
	var list []tissue2
	var total int64
	Db.Model(&a).
		Select("tissue.*,(select count(id) from enterprise where tissue_id = tissue.id) as enterprise_num," +
			"(select count(id) from user where tissue_id = tissue.id) as people_num").
		Order("id desc").
		Find(&list).Offset(-1).Select("id").Count(&total)
	return Db, list, total
}

func (tissue) GetTissueIdArr(id int) string {

	Db := database.DB
	a := tissue{}
	Db.Model(&a).Where("id=?", id).Find(&a)
	idstr := strconv.Itoa(a.ID)
	pid := a.Pid

	if pid > 0 {
		for {
			a = tissue{}
			Db.Model(&a).Where("id=?", pid).Find(&a)

			if a.ID > 0 {
				idstr = strconv.Itoa(a.ID) + "," + idstr
			}
			if a.Pid == 0 {
				break
			}
			pid = a.Pid
		}
	}

	return idstr
}
